機体 インプット/アニメーション 設定
この節を始める前に、(機体 3Dモデル・同期設定)を必ず終わらせてください。
もしくは、FDMi - Exampleパッケージ中に含まれるサンプル例を開いて確認して下さい。
サンプル機に同様の設定を施してあります。お手元に用意して、参考にしてください。
以下の記事内容は、まず文字は見ず、記事中の図とサンプルをみることをお勧めします。
1.概要
この章では、FDMiにおける「入力」と「出力」、「FDMiData」の設定方法を説明します。

入力 / Input
VRやキーボード、もしくは機体自体(オートパイロットなど)や同期による、FDMiへの値の変更を、まとめて「入力」と定義します。
入力は、FDMiData(通常はFDMiFloat)に、「変化量(Value)」と「変化したことを示す通知(Event)」を送信します。
出力 / Output
機体の物理やアニメーション・Transformの移動などを指します。 出力には、以下の2通りの動作パターンが挙げられます。
Update(),FixedUpdate()毎に動作するFDMiDataが変化した際に、FDMiDataから送信される「変化したことを示す通知(Event)」をもらい、そのタイミングで動作する
FDMiData
FDMiDataは「値(Value)」と「変更イベント(Event)」を管理します。
FDMiDataは「値を保持する」機構、とも言えます。
- 「値(Value)」: 入力により入力された値を保持します。出力は値の読み取りができます。
- 「変更イベント(Event)」: 「入力」が値を変化させた際、「出力」から「値が変更した」ことを知らせます。
この設計を行うことで、例えば、一つの入力結果(レバーの操作)を複数の出力に伝えたり、複数の入力結果(例えばVRとキーボード)を一つの入力結果として保持できるようになります。
また、この設計では、ある入力や出力のみのテストの際、仮置きのFDMiDataを用いることで、単機能テストが行いやすくなります。
2 設定方法
以下、例として、ギアレバー及び脚の展開アニメーションを設定します。 今回は、VRのコントローラを上下に動かすと、ギアレバーが動作するように設定します。
2.1 理想状態
- VR上で、ギアレバーに手を重ね「Grab」を行う
- ギアレバーの上下動に関する
FDMiDataの値が変化する FDMiDataの値に応じ、ギアレバーの3Dモデルが動作するFDMiDataの値に応じ、脚の格納アニメーションが動作する
- ギアレバーの上下動に関する
2.2 初期設定
まず、VRにおける入力を、FDMiが受け取るための設定を行います。
FDMiFingerTrackerの準備
まず、FDMiFingerTrackerが準備できていることを確認します。
シーン中FDMi stack/FDMi Input InWorldManagementの中にL,Rと名前のついたFDMiFingerTrackerのComponentがあることを確認してください。
![]()
もし存在しない場合、FDMi stackをPackages/FDMi - Example/Prefabsから配置してください。
詳細はワールドの設定にあります。
FDMiInputManagerの配置
対象としたい飛行機(FDMiObjectManager)の子に、FDMiInputManagerのComponentが設定されたGameObjectを配置します。

2.3 VRによる入力系の配置
では、VRの入力を配置します。ここで、入力の仕組みを説明します。
FDMiInputZoneを、入力対象と一致する位置に用意します。FDMiInputZoneには、1:1対応でFDMiInputPageが紐づいています。FDMiInputZoneの付近でコントローラをGrabすると、FDMiInputPageが呼び出されます。FDMiInputPageは、配下のFDMiInputAddon(今回はFDMiLeverInput)を起動します。FDMiInputAddonは、そのときの手の位置・回転・ボタンの状態を読み取り、結果をFDMiData(今回はFDMiFloat)に渡します。

以下、各項目の設定を説明します。
2.3.1 FDMiInputPage
まず、FDMiInputPageを配置します。
Vechicle/Modelの子に配置します。ほかの入力系を設定する事を踏まえ、今回はVechicle/Model/Input/GearLeverに配置しました。
内部の値は後程の操作で自動設定されます。

2.3.2 FDMiInputZone
FDMiInputZoneを設置します。
今回は、(最終的に動作する)ギアレバーに追従させるため、ギアレバーのボーンの子にGameObjectを作成し配置します。

- 上図の様に、
Is Triggerを有効化したCollierと同じGameObjectにFDMiInputZoneを配置します。 InputPageに、先程配置したGearLeverのFDMiInputPageを設定します。- Hilight Objectには、下図の様な手を近づけた際にハイライトとして光らせたいGameObjectを設定します。
今回の場合、FDMiInputZoneの子にSphereの3Dモデルを配置し、GameObjectをfalseにしています。
モデルの制作時、レバー毎にGameObjectを分割すると、レバーにHilightをつけられます。
2.3.3 FDMiLeverInput (+ FDMiDataBusTerminal)
次に、レバーによる動作自体を設定していきます。
まず、Vechicle/Model/Input/GearLeverの子に、FDMiDataBusTerminalを配置します。
そして、その子にFDMiLeverInputを配置します。

FDMiLeverInputのLeverOutputにはFDMiFloatが入ります。FDMiFloatはFDMiDataの一種で、float値を格納します。
FDMiLeverInputはLeverOutputの値を変更するとともに、変更イベントをLeverOutputに発行します。
以下、FDMiLeverInputの各項目を設定していきます。
-
まず、LeverInputのTransformの位置を”レバーの根本”に持ってきてください。 Leverを手で回したり(Rotate)、ひねったり(Twist)する動作の際の、レバーの根本を示します。
-
Control TypeとLever Axisを設定します。-
Pull: 平行移動による入力量を指します。GrabをしながらLever Axisで設定した方向(このTransformの矢印)に手を動かした量を、Lever Outputに加算します。単位は1/mです。 -
Rotate: Transformを原点とした、回転による入力量を指します。現在のTransformをレバーの支点、Lever Axisを回転軸とした回転移動量をLever Outputに加算します。単位は1/°です。 -
Twist: ひねりによる入力量を指します。Grab中のコントローラー自体の回転量から、Lever Axisで設定した軸周りの回転量を取り出し、Lever Outputに加算します。単位は1/°です。
-
-
multplier,min,maxを設定します。- Grabをすると、
LeverOutput=Clamp(LeverOutput + (変化量)* multiplier,min,max)の結果をLeverOutputに格納します。
今回は以下の設定にします。 multplier:1/60 60°回転させたら「1」になるよう、を代入します。min: 0max: 1
- Grabをすると、
-
Detents手を離した際、Detentsに最も近い値にLeverOutputを設定します。
Detentsに何も設定しなければ、この動作は発生せず、最後に手を離した位置がレバーの位置になります。
今回は、ギアレバーの結果なので[0,1]を設定しています。
2.3.4 FDMiData(FDMiDataBusTerminalを使用)
最後に、FDMiDataを設定します。入力結果の値を保存するため,FDMiLeverInputのLeverOutputにFDMiFloatを配置します。
ここで、そのまま行ってもよいのですが、FDMiでは大量のFDMiDataを配線が必要になる関係上、無秩序にFDMiFloatを増やすと大変なことになります。(なりました。)
そこで、FDMiDataの配置を自動化する、FDMiDataBusとFDMiDataBusTerminalを使用します。
さて、2.3.3ではVechicle/Model/Input/GearLever/GearLever(FDMiLeverInputの親)にFDMiDataBusTerminalを配置したかと思います。FDMiDataBusTerminal「+」ボタンを押して、以下を追加します。

- チェックボックス:☑(有効)
- ☑(有効):この機体全体に設定を波及させます。
- ☐(無効):この
FDMiDataBusTerminalの子のみで使用する変数として扱います。
global Name: "GearLever"- 機体全体で、この変数を指す名前として使用します。
FDMiDataBusTerminalは、ここで設定した名前をもとに、"GearLever"を探し(無ければ自動生成し)ます。
- 機体全体で、この変数を指す名前として使用します。
local Name: "LeverOutput"FDMiDataBusTerminalの子にあるComponentの、FDMiDataを代入する項目の変数名がlocal Nameと一致した際、Global Nameで紐づいたFDMiDataを自動で代入します。
- 変数型:
FDMiFloat- 変数型を指定します。
local Nameの示す代入先に応じたFDMiDataの型を選択してください。 今回、LeverOutputはFDMiFloatを代入すべき項目ですので、FDMiFloatを選択します。
- 変数型を指定します。
2.3.5 自動設定
ここまで設定したら、Unity上部のメニューからFDMi/Setup All FDMi Componentsを選択してください。
自動設定すべき場所に、変数が自動配置されます。
自動配置される場所は、以下の通りです。
- FDMiData型(FDMiBool,FDMiFloat, FDMiVector3, FDMiSyncedFloat等)が代入される箇所
- 変数の横に"Find"のボタンがある箇所
2.4 出力:ギアレバーの動作(FDMiTransformRotationDriver)
入力の結果を、出力に適用してみましょう。
まず、ギアレバーを動作させてみます。Vechicle/Model/Input/GearLeverの子に、FDMiTransformRotationDriverを含むGameObjectを作成します。

FDMiTransformRotationDriverは、FDMiDataに応じ、Transformを回転させます。
Value: のちほどFDMiDataBusTerminalで設定されます。RotateTransform: 回転させたいTransformを選択します。今回はギアレバーに紐づいたボーンを選択しています。RotateAxis: 回転させたい軸を選択します。軸はRotateTransformの、ローカルの軸です。Multiplier:ValueのFDMiFloatが持つ値に対し、RotateTransformを何°回転させたいかを設定します。repeatValue:Valueの値に対し、繰り返しを設定します。計器の針など、一定の値(100ftとか)で0に戻したいときに使用します。
また、以下を設定します。以下は、負荷などを考えて使用してください。
moveOnValueChange: ☑(有効)- FDMiDataが「値の変更に伴うイベント」を受け取るたびに、Transformを回転させます
- 毎フレーム動作すると
moveOnUpdateより重いですが、数分に一回呼ばれる程度であればこちらの方が軽量です。
moveOnUpdate: ☐(無効)- Update毎にTransformを回転させます。
- 毎フレーム動作するもの(計器など)では、
moveOnValueChangeより軽くなります。
次に、FDMiDataBusTerminalに、以下を追加します。
- チェックボックス:☑(有効)
global Name: "GearLever"local Name: "Value"- 変数型:
FDMiFloat
ここまで設定されていれば、以下の状態になるはずです。
ここでUnity上部メニューからFDMi/Setup All FDMi Componentsを選択し、自動設定を実行してください。

ここまでできたら、VRChatでワールドに入り、椅子に座り、レバーを握ってみてください。
正常に設定できていれば、手の動きに応じてレバーが動作するはずです。
上手くいかないときは,FDMiLeverInputのMuiltiplier、およびFDMiTransformRotationDriverのMuiltiplierを確認してください。
2.5 出力:ギア格納・展開(FDMiAnimatorDriver)
ここでは、「見た目」の変化のみを設定します。WheelColliderの設定は別で行います。
次に、ギアの格納アニメーションを作成してみます。
まず、ギアの格納をAnimatorに設定します。Animatorの設定については、モデル差がありますので詳細は割愛します。
今回は、以下の様なAnimatorを作成しました。
- パラメータ
gearの値に応じて、ギアが展開する - 0: 展開状態- 1: 格納状態
ここで、FDMiDataの値を用いてAnimatorのパラメータを変化させていきます。
ただし、GearLeverの値そのままだと、脚の格納が一瞬で終わってしまうため、「GearLeverを1にしたら、ゆっくり格納される」挙動を作成していきます。
完成形は以下の図に示す通りです。
GearLeverの値にディレイ(遅れ)をかけたFDMiFloat、GearRetractを用意し、その値をAnimatorに書き込みます。

2.5.1 ディレイ(FDMiFloatMixer)
まず、GearLeverの値にディレイをかけます。これにはFDMiFloatMixerを使用します。
今回はVehicle/Control/Gearの子にFDMiFloatMixerを作成します。

各項目は以下の通り設定します。
output: 出力先のFDMiFloatを設定します。- 今回は
Vehicle/Control/GearにFDMiDataBusTermianlを置き、自動設定します。
- 今回は
data: 入力のFDMiFloatを設定します。Outputは、各dataの総和に対しディレイやOutput Curveをかけた結果が代入されます。- 今回は
Vehicle/Control/GearにFDMiDataBusTermianlを置き、自動設定します。
T: 0.2 = 1/5(s)- 入力に対する出力の遅れを定義します。
- 今回は、5秒かけて脚を展開してほしいため、1/5=0.2を設定します
outputCurve: 入力の総和に対し、出力のマッピングを行います。横軸がdataの総和・縦軸がOutputになります- 今回は
dataの総和とOutputが1:1対応になるような設定にします
- 今回は
useUpdate: ☐(無効)- Update()毎に
Outputを変更します
- Update()毎に
useOnChange: ☑(有効)- 各
dataが変更される毎にOutputを変更します
- 各
次に、Vehicle/Control/GearにFDMiDataBusTermianlを配置します。

GearRetract:出力です。です。FDMiFloatMixerのoutputに代入されるよう設定します。GearLever: 入力です。FDMiFloatMixerのdataに代入されるよう設定します。
FDMiData(FDMiFloat等)の配列に、FDMiDataBusTermianlから代入したいときは、配列の順に、配列名を書いてください。
(複数個のFDMiDataを、FDMiDataBusTerminalから代入することができます。)
local Nameに入れる名称の正しい綴り(大文字/小文字)などがわからないときは、代入したい項目を**右クリックし、Copy Property Path**を行えば、正式名称をクリップボードにコピーできます。

2.5.2 ギア格納・展開(FDMiAnimatorDriver)
次に、Animatorを動かしていきます。
まず、Animatorを設定します。今回はVehicle/ModelにAnimatorコンポーネントを配置しました。
今回は、"gear"パラメータに応じて、脚の位置を稼働させるAnimationが配置されています。

それでは、Vechicleと同じ階層にあるAnimationDriver以下に、"gear"パラメータを変化させるFDMiAnimatorDriverを設定します。

AnimatorDriver/GearにFDMiDataBusTerminalを配置します。GearRetractを、配下のInputに自動設定されるよう設定します。
AnimatorDriver/Gearの子にFDMiAnimatorDriverを配置します。Input: 入力です。FDMiDataBusTerminalから設定されます。Animator: パラメータを変更させたい対象のAnimatorを設定します。今回はVehicle/Modelを選択しています。Paramator:Animator内の、値を変化させたいパラメータに対応する文字列を記入します。今回は"gear"です。outputValue: 横軸Input対し、縦軸Paramatorの値をどのように変化させるかを設定します
ここまでできたら、Unity上部メニューからFDMi/Setup All FDMi Componentsを選択し、自動設定を実行してください。
VRChat上で、ギアレバーを動かすと、脚が格納するようになります。
3. 同期の設定
このままでは、脚の格納・展開状態を、自分以外の人に伝えられないので、同期を設定します。 同期の設定方法は2通りあります。
FDMiFloatをFDMiSyncedFloatに置き換えるFDMiSynedFloatArrayを使用する
今回は後者を使用します。
前者に対する後者のメリットは、同期したい/したくないを後から変更・管理しやすい点です。
(FDMiSyncedFloatを使うと、何が同期対象なのか分かりづらくなってしまう、それだけです。好みで使ってください。)
今回は、GearLeverを同期対象とします。直接的な展開・格納状態(GearRetract)は同期せず各個で計算する形にします。

Vehicle/Sync/InputPeripheralにFDMiDatabusTerminalを配置します。GearLeverをFDMiDatabusTerminal配下のdataに自動設定されるよう設定します。
Vehicle/Sync/InputPeripheralの子にFDMiSyncedFloatArrayを配置します。
ここまでできたら、Unity上部メニューからFDMi/Setup All FDMi Componentsを選択し、自動設定を実行してください。
これで、脚の格納状態が同期されるようになります。
4.アニメーション デバッグ
ここまでで、アニメーションが設定されたかどうかのテストを簡潔に行う方法を解説します。
FDMi/Setup All FDMi Componentsを押した後、Unity上でPlayモードにします。

Vehicle/Data(自動生成されたFDMiData)からGearLeverを探します。FDMiFloatのDataの数字を"0"⇒"1"にしてみます。ClientSimUdonHelperのRun Custom Eventから"trigger"を押します- ギアレバーの動作と、ギアの格納をチェックします。
ここで、ギアレバーの位置・回転量がずれていたり、ギア格納アニメーションの速度見てみます。
おかしい場合は、各項目にもどって、パラメータを確認します。